PORTING THE PROCESS CLASSES

This section describes the steps to follow if you want to be a pioneer and port the Process classes to a new machine/operating system.

If your target system provides the C library routines setjmp(), longjmp(), and alloca(), and if the implementation of setjmp()/longjmp() operates by saving/restoring all of the machine's volatile registers (as they do on the Sun-3, Sun-4, and IBM RT/AOS), then the port should be very easy; otherwise, you'll need to write versions of these routines in assembly language that behave as expected.

To find out how your setjmp()/longjmp() works, either look at the source code for these routines (if you're fortunate enough to have it) or use the debugger to disassemble them. A data structure of type jmp_buf, defined in setjmp.h, is passed as an argument to these routines. If your setjmp() just saves all the volatile registers in it to be restored later by longjmp(), then you're probably in luckā€”all you need to figure out are the offsets in the jmp_buf structure where the PC (Program Counter), SP (Stack Pointer), and FP (Frame Pointer) registers are saved.

Next, look at nihclconfig.h and locate the place where it defines the machine-specific inline functions SETJMP(), LONGJMP(), _SETJMP(), _LONGJMP(), ENV_PC(), ENV_SP(), and ENV_FP(). These define the interface to the Process classes. For example, here are the definitions for SunOS 4.0 on the Sun-3:

#ifdef SUNOS4

#ifdef mc68000

typedef jmp_buf JMP_BUF;

inline int SETJMP(JMP_BUF env) { return setjmp(env); }

inline void LONGJMP(JMP_BUF env, int val) { longjmp(env,val); }

inline int _SETJMP(JMP_BUF env) { return _setjmp(env); }

inline void _LONGJMP(JMP_BUF env, int val) { _longjmp(env,val); }

inline unsigned& ENV_PC(JMP_BUF env)

{ return (unsigned&)env[3]; }

inline unsigned& ENV_SP(JMP_BUF env)

{ return (unsigned&)env[2]; }

inline unsigned& ENV_FP(JMP_BUF env)

{ return (unsigned&)env[15]; }

#endif

// ...

#endif

Add an #if ... #endif section for your machine and define the ENV_PC(), ENV_SP(), and ENV_FP() functions to return a reference to the appropriate word in the JMP_BUF array.

If your machine doesn't use both an SP and FP, then you'll also need to add some machine dependent C++ code to HeapProc.c to relocate only the one actually used. See the code for the ibm032 in HeapProc.c as an example.

If your system has both setjmp()/longjmp() and _setjmp()/_longjmp(), define SETJMP(), LONGJMP(), _SETJMP(), and _LONGJMP() to call the corresponding routine. If your system doesn't have the "_" versions, check your documentation to see if your setjmp()/longjmp() saves and restores the signal mask; if so, define _SETJMP() and _LONGJMP() to call setjmp() and longjmp(), respectively. See the code for SUNOS3 as an example.

If your setjmp() and longjmp() do not save and restore the signal mask, you'll need to provide versions that do. Define JMP_BUF to be a struct that consists of a jmp_buf plus whatever other members you need to save the signal mask. Then define _SETJMP() and _LONGJMP() to call setjmp() and longjmp() using the jmp_buf part of a JMP_BUF, and define SETJMP() and LONGJMP() to do the same, but in addition to save/restore the signal mask using the other members of a JMP_BUF. See the code for the mc300 as an example.

If your setjmp()/longjmp() do not work by saving/restoring all volatile registers (as on the VAX), you'll need to write versions with different names that do, and call these instead from the interface functions.

If you succeed in porting the Process classes to a new machine/operating system, we'd appreciate a copy of the code for inclusion in future releases.